﻿#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "src/ui_DialogSetCurve.h"
#include <QTreeView>
#include <qcustomplot.h>
#include <DockManager.h>
#include <DockWidget.h>
#include <DockAreaWidget.h>
#include <QFileDialog>
#include <ElementTreeItem.h>
#include <ElementTreeModel.h>
#include <ElementsReader.h>
#include <QColor>
#include <QRandomGenerator>
#include <DialogSetCurve.h>
#include <ListWidgetItem.h>
#include "OutputData.h"
#include "OutputPicture.h"
#include "TreeFilterProxyModel.h"
#include "ElementTreeItem.h"
static const int baseTableCount=6;
static const QStringList baseTableColNames = QStringList() << "曲线" << "文件" << "T1" << "Y1" << "T2" << "Y2";
using namespace ads;
struct MainWindowPrivate
{
    MainWindow *w;
    ads::CDockManager *mDockManager;
    static std::uniform_int_distribution<> dis;
    static bool isfirst;
    static std::mt19937 gen;
    MainWindowPrivate(MainWindow *w)
        : w(w)
    {
        w->setStyleSheet("QToolButton {"
                         "   background-color: #f0f0f0;"
                         "   border-radius: 5px;"
                         "   padding: 2px;"
                         "}"
                         "QToolButton:hover {"
                         "   background-color: #e0e0e0;"
                         "}"
                         "QToolButton:checked {"
                         "   background-color: #4a90e2;"
                         "   color: #ffffff;"
                         "}");
        createCustomPlot();
        createDocks();
        // w->resize(800,600);
    }
    void createCustomPlot();
    void createDocks();
    static QColor getRandomColor();
};
bool MainWindowPrivate::isfirst = true;
std::mt19937 MainWindowPrivate::gen = std::mt19937(42);
std::uniform_int_distribution<> MainWindowPrivate::dis = std::uniform_int_distribution<>(0, 255);
void MainWindowPrivate::createCustomPlot()
{
    /*添加标题： 顶层布局设置， 插入一行空的单元格*/
    w->ui->customPlot->plotLayout()->insertRow(0);
    // 中文字符串需要转换后使用  QString::fromLocal8Bit("交互")
    /*文本布局*/
    QCPTextElement *title = new QCPTextElement(w->ui->customPlot, "曲线");
    QFont font("Arial", 18, QFont::Bold); // 字体名、字号、是否加粗
    title->setFont(font);
    w->ui->customPlot->plotLayout()->addElement(0, 0, title); // 添加位置0行0列  AI
                                                              //  启用交互功能
    w->ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

    /*图例设置，设置图例内容可选*/
    w->ui->customPlot->legend->setVisible(true);

    w->ui->customPlot->setDragModel();
}

void MainWindowPrivate::createDocks()
{
    w->mListWidgetSelectDatas->setStyleSheet(
        "QListWidget {"
        "   border: 1px solid #d3d3d3;"
        "   border-radius: 5px;"
        "   padding: 5px;"
        "}"
        "QListWidget::item {"
        "   color: #333333;"
        "   background-color: #ffffff;"
        "   padding: 5px;"
        "   border-bottom: 1px solid #d3d3d3;"
        "}"
        "QListWidget::item:selected {"
        "   color: #ffffff;"
        "   background-color: #4a90e2;"
        "   border: none;"
        "}"
        "QListWidget::item:pressed {"
        "   color: #ffffff;"
        "   background-color: #4a90e2;"
        "   border: none;"
        "}"
        "QListWidget::item:hover {"
        "   background-color: #87CEEB;"
        "}");
    CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
    CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
    CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
    mDockManager = new ads::CDockManager(w);
    ads::CDockWidget *CentralDockWidget = new ads::CDockWidget("CentralWidget");
    CentralDockWidget->setWidget(w->ui->customPlot);
    auto *CentralDockArea = mDockManager->setCentralWidget(CentralDockWidget);
    CentralDockArea->setAllowedAreas(BottomDockWidgetArea);

    ads::CDockWidget *TableDockWidget = new ads::CDockWidget("文件");
    TableDockWidget->setWidget(w->ui->fleWidget);
    TableDockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromDockWidget);
    TableDockWidget->resize(w->ui->treeView->minimumWidth(), 150);
    TableDockWidget->setMinimumSize(200, 150);
    auto *leftDockArea = mDockManager->addDockWidget(ads::DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
    leftDockArea->setMaximumWidth(350);
    // leftDockArea->setAllowedAreas(ads::LeftDockWidgetArea | ads::RightDockWidgetArea);

    TableDockWidget = new CDockWidget("选择的曲线");
    TableDockWidget->setWidget(w->mListWidgetSelectDatas);
    TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
    TableDockWidget->resize(250, 150);
    TableDockWidget->setMinimumSize(200, 150);
    mDockManager->addDockWidget(ads::DockWidgetArea::BottomDockWidgetArea, TableDockWidget, leftDockArea);

    TableDockWidget = new CDockWidget("消息");
    auto *bottomDockArea = mDockManager->addDockWidget(ads::DockWidgetArea::BottomDockWidgetArea, TableDockWidget, CentralDockArea);
    TableDockWidget->setWidget(w->mTextEditMessage);
    TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
    TableDockWidget->resize(250, 150);
    TableDockWidget->setMinimumSize(200, 150);

    TableDockWidget = new CDockWidget("测值");
    TableDockWidget->setWidget(w->mTableWidgetMeasurement);
    mDockManager->addDockWidgetTabToArea(TableDockWidget, bottomDockArea);
}

QColor MainWindowPrivate::getRandomColor()
{
    int red = dis(gen);
    int green = dis(gen);
    int blue = dis(gen);
    return QColor(red, green, blue);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow), mpFilterProxyModel(new TreeFilterProxyModel(this)), mListWidgetSelectDatas(new QListWidget(this)), mTextEditMessage(new QPlainTextEdit(this)), mDialogSetCurve(new DialogSetCurve()), mTableWidgetMeasurement(new QTableWidget(this))
{
    ui->setupUi(this);
    mListWidgetSelectDatas->setContextMenuPolicy(Qt::CustomContextMenu);
    mTreeModel = new ElementTreeModel(ui->treeView);
    mTreeModeReader = new ElementsReader();
    mpFilterProxyModel->setSourceModel(mTreeModel);
    ui->treeView->setModel(mpFilterProxyModel);
    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    mPrivate = new MainWindowPrivate(this);
    mDialogSetCurve->setWindowTitle("曲线设置");
    mDialogSetCurve->setWindowIcon(QIcon(":/images/loge.svg"));
    initForm();
    bind();
    ui->actionMeasurement->setChecked(true);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onActionOpenFileTriggered()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "选择文件", ".", "psmodel(*.out);;csv(*.csv);;excel(*.xlsx)");
    if (fileNames.count() == 0)
    {
        return;
    }
    openFiles(fileNames);
}

void MainWindow::onTreeViewDoubleClicked(const QModelIndex &index)
{
    QModelIndex temI = mpFilterProxyModel->mapToSource(index);
    ElementTreeItem *d = (ElementTreeItem *)temI.internalPointer();
    if (!d || mSetSelectDatas.count(d))
        return;
    if (d->isLeaf())
    {
        mSetSelectDatas.insert(d);

        QCPGraph *graph = ui->customPlot->addGraph();
        graph->setName(d->value(0).toString());
        graph->setPen(MainWindowPrivate::getRandomColor());
        ListWidgetItem *item = new ListWidgetItem(d->value(0).toString(), d, mListWidgetSelectDatas);
        item->SetGraph(graph);

        graph->setData(item->xData(), item->yData());
        // 设置坐标轴范围
        mYMaxData = std::fmax(mYMaxData, item->yMaxData());
        mYMinData = std::fmin(mYMinData, item->yMinData());
        mXMaxData = std::fmax(mXMaxData, item->xMaxData());
        mXMinData = std::fmin(mXMinData, item->xMinData());
        adjustPlotAxis();
        // 重新调整大小
        ui->customPlot->replot();
        item->setCheckState(Qt::CheckState::Checked);
        addValueOfMeasurement(item);
    }
}

void MainWindow::onListWidgetSelectDatasDoubleClicked(const QModelIndex &index)
{
    ListWidgetItem *item = (ListWidgetItem *)mListWidgetSelectDatas->item(index.row());
    mDialogSetCurve->setTitle(item->text());
    mDialogSetCurve->ui->doubleSpinBoxA->setValue(item->A());
    mDialogSetCurve->ui->doubleSpinBoxDT->setValue(item->dt());
    mDialogSetCurve->ui->doubleSpinBoxB->setValue(item->B());
    mDialogSetCurve->show();
    mDialogSetCurve->setSelectColor(item->graph()->pen().color());
    if (mDialogSetCurve->exec() == QDialog::Accepted)
    {
        item->setA(mDialogSetCurve->ui->doubleSpinBoxA->value());
        item->setDt(mDialogSetCurve->ui->doubleSpinBoxDT->value());
        item->setB(mDialogSetCurve->ui->doubleSpinBoxB->value());
        item->updateGraphData();
        item->graph()->setPen(QPen(mDialogSetCurve->selectColor()));
        ui->customPlot->replot();
    }
}

void MainWindow::onListWidgetSelectDatasItemChanged(QListWidgetItem *item)
{
    if (!item)
    {
        return;
    }
    if (item->checkState())
    {
        ui->customPlot->graph(mListWidgetSelectDatas->indexFromItem(item).row())->setVisible(true);
        ui->customPlot->replot();
        mSelectedCount += 1;
    }
    else
    {
        ui->customPlot->graph(mListWidgetSelectDatas->indexFromItem(item).row())->setVisible(false);
        ui->customPlot->replot();
        mSelectedCount -= 1;
    }
}

void MainWindow::onListWidgetSelectDatasCustomContextMenuRequested(const QPoint &pos)
{
    QModelIndex index = mListWidgetSelectDatas->indexAt(pos);
    if (!index.isValid())
    {
        return;
    }
    QMenu menu;
    QAction *del = menu.addAction("删除");
    QPoint globalPos = mListWidgetSelectDatas->viewport()->mapToGlobal(pos);
    QAction *sel = menu.exec(globalPos);
    if (sel == del)
    {
        auto item = (ListWidgetItem *)index.internalPointer();
        removeListWidgetItem(item);
    }
}

void MainWindow::on_actionClear_triggered()
{
    // 清空图像
    ui->customPlot->clearGraphs();
    //
    mYMaxData = std::numeric_limits<double>::min();
    mYMinData = std::numeric_limits<double>::max();
    mXMaxData = std::numeric_limits<double>::min();
    mXMinData = std::numeric_limits<double>::max();

    this->mSetSelectDatas.clear();
    mListWidgetSelectDatas->clear();
    mTableWidgetMeasurement->setRowCount(0);
    ui->customPlot->setLeftRightLine(0,0);
    ui->customPlot->replot();
    mSelectedCount = 0;
}

void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    auto arg = "*" + arg1 + "*";
    mpFilterProxyModel->setFilterWildcard(arg);
    mpFilterProxyModel->setFilterKeyColumn(0);
}

void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{
    QModelIndex index = ui->treeView->indexAt(pos);
    if (!index.isValid())
    {
        return;
    }
    QModelIndex indexSource = this->mpFilterProxyModel->mapToSource(index);
    ElementTreeItem *ite = (ElementTreeItem *)indexSource.internalPointer();
    QMenu menu;
    QAction *del = nullptr;
    QAction *view = nullptr;
    QAction *refresh = nullptr;
    if (!ite->isLeaf())
    {
        del = menu.addAction("删除");
        refresh = menu.addAction("刷新");
    }
    else
    {
        view = menu.addAction("显示");
    }
    QPoint globalPos = ui->treeView->viewport()->mapToGlobal(pos);
    QAction *sel = menu.exec(globalPos);
    if (del && sel == del)
    {
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(this, "确认删除", "确定要删除该子树吗？",
                                      QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
        if (reply == QMessageBox::Yes)
        {
            if (!ite->isLeaf())
            {
                mOpenFiles.erase(ite->value(Qt::DisplayRole).toString());
                int count = mListWidgetSelectDatas->count();
                for (int i = 0; i < count; ++i)
                {
                    removeListWidgetItem(0);
                }
            }
            else
            {
                int count = mListWidgetSelectDatas->count();
                for (int i = 0; i < count; ++i)
                {
                    auto listItem = (ListWidgetItem *)(mListWidgetSelectDatas->item(i));
                    if (listItem->text() == ite->value(Qt::DisplayRole).toString())
                    {
                        removeListWidgetItem(listItem);
                    }
                }
            }
            mTreeModel->removeRow(ite->rowOnParent(), indexSource.parent());
        }
    }
    else if (view && sel == view)
    {
        onTreeViewDoubleClicked(index);
    }
    else if (refresh && sel == refresh)
    {
        QString fileName = ite->value(Qt::DisplayRole).toString();
        mOpenFiles.erase(fileName);
        mTreeModel->removeRow(ite->rowOnParent(), indexSource.parent());
        openFile(fileName);
    }
}

void MainWindow::on_actionExport_triggered()
{
    OutputData *outputData = new OutputData(this->mTreeModel, mListWidgetSelectDatas, this);
    if (outputData->exec() == QDialog::Accepted)
    {
    }
    delete outputData;
}

void MainWindow::on_actionExportPicture_triggered()
{
    OutputPicture *outputPicture = new OutputPicture(this->ui->customPlot, this);
    outputPicture->exec();
    delete outputPicture;
}

void MainWindow::on_actionOriginal_triggered()
{
    adjustPlotAxis();
    ui->customPlot->replot();
}

void MainWindow::on_actionMeasurement_toggled(bool checked)
{
    ui->customPlot->setMeasureLineVisible(checked);
}

void MainWindow::initForm()
{
    mTableWidgetMeasurement->setColumnCount(baseTableCount);
    mTableWidgetMeasurement->setHorizontalHeaderLabels(QStringList() << "曲线" << "文件" << "X1" << "Y1" << "X2" << "Y2");
    mTableWidgetMeasurement->setRowCount(0);
    ui->actionMeasurement->setCheckable(true);
    ui->actionMinValue->setCheckable(true);
    ui->actionMaxValue->setCheckable(true);
    ui->actionDifference->setCheckable(true);
}

void MainWindow::bind()
{
    MainWindow::connect(mListWidgetSelectDatas, &QListWidget::doubleClicked, this, &MainWindow::onListWidgetSelectDatasDoubleClicked);
    MainWindow::connect(mListWidgetSelectDatas, &QListWidget::itemChanged, this, &MainWindow::onListWidgetSelectDatasItemChanged);
    MainWindow::connect(mListWidgetSelectDatas, &QListWidget::customContextMenuRequested, this, &MainWindow::onListWidgetSelectDatasCustomContextMenuRequested);
    connect(ui->actionOpenFile, &QAction::triggered, this, &MainWindow::onActionOpenFileTriggered);
    connect(ui->treeView, &QTreeView::doubleClicked, this, &MainWindow::onTreeViewDoubleClicked); // onTreeViewDoubleClicked
    connect(ui->actionMinValue,&QAction::toggled,this,&MainWindow::updateMeasurementTable);
    connect(ui->actionMaxValue,&QAction::toggled,this,&MainWindow::updateMeasurementTable);
    connect(ui->actionDifference,&QAction::toggled,this,&MainWindow::updateMeasurementTable);
    connect(ui->customPlot,&MyCustomPlot::leftLineChanged,this,&MainWindow::updateMeasurementTable);
    connect(ui->customPlot,&MyCustomPlot::rightLineChanged,this,&MainWindow::updateMeasurementTable);
    void rightLineChanged(double v);
}

void MainWindow::removeListWidgetItem(ListWidgetItem *item)
{
    if (!item)
    {
        return;
    }
    if (item->checkState())
    {
        mSelectedCount -= 1;
    }
    ui->customPlot->removeGraph(item->graph());
    int row = mListWidgetSelectDatas->row(item);
    mListWidgetSelectDatas->takeItem(row);
    mSetSelectDatas.erase(item->elementTreeItem());
    delete item; // 释放内存
    ListWidgetItem *it = nullptr;
    mXMaxData = std::numeric_limits<double>::min();
    mYMaxData = std::numeric_limits<double>::min();
    mXMinData = std::numeric_limits<double>::max();
    mYMinData = std::numeric_limits<double>::max();
    int count = mListWidgetSelectDatas->count();
    for (int i = 0; i < count; ++i)
    {
        it = (ListWidgetItem *)mListWidgetSelectDatas->item(i);
        mXMaxData = std::max(mXMaxData, it->xMaxData());
        mYMaxData = std::max(mYMaxData, it->yMaxData());
        mXMinData = std::min(mXMinData, it->xMinData());
        mYMinData = std::min(mYMinData, it->yMinData());
    }
    adjustPlotAxis();
    ui->customPlot->replot();
}

void MainWindow::removeListWidgetItem(int index)
{
    auto item = (ListWidgetItem *)mListWidgetSelectDatas->item(index);
    if (!item)
    {
        return;
    }
    if (item->checkState())
    {
        mSelectedCount -= 1;
    }
    ui->customPlot->removeGraph(item->graph());
    mListWidgetSelectDatas->takeItem(index);
    mSetSelectDatas.erase(item->elementTreeItem());
    delete item; // 释放内存
    ui->customPlot->replot();
}

int MainWindow::getMeasurementTableColCount()
{
    int c = baseTableCount;
    c += ui->actionMinValue->isChecked()*2;
    c += ui->actionMaxValue->isChecked()*2;
    c += ui->actionDifference->isChecked()*2;
    return c;
}

void MainWindow::addValueOfMeasurement(ListWidgetItem *item)
{
    updateMeasurementTableColumn();
    mTableWidgetMeasurement->insertRow(mTableWidgetMeasurement->rowCount());
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 0,new QTableWidgetItem(item->text()));
    mTableWidgetMeasurement->item(mTableWidgetMeasurement->rowCount() - 1, 0)->setData(Qt::UserRole, (unsigned long long)item);
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 1,new QTableWidgetItem(item->elementTreeItem()->parent()->value(Qt::DisplayRole).toString()));
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 2,new QTableWidgetItem());
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 3,new QTableWidgetItem());
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 4,new QTableWidgetItem());
    mTableWidgetMeasurement->setItem(mTableWidgetMeasurement->rowCount() - 1, 5,new QTableWidgetItem());
    updateMeasurement(mTableWidgetMeasurement->rowCount() - 1);
}

template <typename VECTOR, typename T>
int searchsorted(const VECTOR &sortedArray, T value)
{
    // 使用 std::lower_bound 查找第一个不小于 value 的位置
    auto it = std::lower_bound(sortedArray.begin(), sortedArray.end(), value);
    return std::distance(sortedArray.begin(), it);
}

void MainWindow::updateMeasurement(int row)
{
    ListWidgetItem *item = (ListWidgetItem *)mTableWidgetMeasurement->item(row, 0)->data(Qt::UserRole).toULongLong();
    if (!ui->actionMeasurement->isChecked())
    {
        return;
    }
    mTableWidgetMeasurement->item(row, 2)->setText(QString::number(ui->customPlot->leftLine()));
    if (ui->customPlot->leftLine() >= item->xMinData() && ui->customPlot->leftLine() <= item->xMaxData())
    {
        int index = searchsorted(item->xData(), ui->customPlot->leftLine());
        mTableWidgetMeasurement->item(row, 3)->setText(QString::number(item->yData()[index]));
    }
    mTableWidgetMeasurement->item(row, 4)->setText(QString::number(ui->customPlot->rightLine()));
    if (ui->customPlot->rightLine() >= item->xMinData() && ui->customPlot->rightLine() <= item->xMaxData())
    {
        int index = searchsorted(item->xData(), ui->customPlot->rightLine());
        mTableWidgetMeasurement->item(row, 5)->setText(QString::number(item->yData()[index]));
    }
    mTableWidgetMeasurement->setColumnCount(getMeasurementTableColCount());
    int index = baseTableCount;
    if (ui->actionMinValue->isChecked())
    {
        if(!mTableWidgetMeasurement->item(row, index)){
            mTableWidgetMeasurement->setItem(row,index,new QTableWidgetItem());
        }
        if(!mTableWidgetMeasurement->item(row, index+1)){
            mTableWidgetMeasurement->setItem(row,index+1,new QTableWidgetItem());
        }
        int i = item->yMinDataIndex();
        mTableWidgetMeasurement->item(row, index)->setText(QString::number(item->xData()[i]));
        mTableWidgetMeasurement->item(row, index+1)->setText(QString::number(item->yMinData()));
        index+=2;
    }
    if (ui->actionMaxValue->isChecked())
    {
        if(!mTableWidgetMeasurement->item(row, index)){
            mTableWidgetMeasurement->setItem(row,index,new QTableWidgetItem());
        }
        if(!mTableWidgetMeasurement->item(row, index+1)){
            mTableWidgetMeasurement->setItem(row,index+1,new QTableWidgetItem());
        }
        int i = item->yMaxDataIndex();
        mTableWidgetMeasurement->item(row, index)->setText(QString::number(item->xData()[i]));
        mTableWidgetMeasurement->item(row, index+1)->setText(QString::number(item->yMaxData()));
        index+=2;
    }
    if (ui->actionDifference->isChecked())
    {
        if(!mTableWidgetMeasurement->item(row, index)){
            mTableWidgetMeasurement->setItem(row,index,new QTableWidgetItem());
        }
        if(!mTableWidgetMeasurement->item(row, index+1)){
            mTableWidgetMeasurement->setItem(row,index+1,new QTableWidgetItem());
        }
        int leftIndex = searchsorted(item->xData(), ui->customPlot->leftLine());
        auto left = item->yData()[leftIndex];
        int rightIndex = searchsorted(item->xData(), ui->customPlot->rightLine());
        auto right = item->yData()[rightIndex];

        mTableWidgetMeasurement->item(row, index)->setText(QString::number(item->xData()[rightIndex]-item->xData()[leftIndex]));
        mTableWidgetMeasurement->item(row, index+1)->setText(QString::number(right-left));
        index+=2;
    }
}

void MainWindow::updateMeasurementTableColumn()
{
    int c = getMeasurementTableColCount();
    mTableWidgetMeasurement->setColumnCount(c);
    QStringList labels=baseTableColNames;
    if (ui->actionMinValue->isChecked())
    {
        labels<<"最小值时间点";
        labels<<"最小值";
    }
    if (ui->actionMaxValue->isChecked())
    {
        labels<<"最大值时间点";
        labels<<"最大值";
    }
    if (ui->actionDifference->isChecked())
    {
        labels<<"测直线时间差";
        labels<<"测直线数据差";
    }
    mTableWidgetMeasurement->setHorizontalHeaderLabels(labels);
}

void MainWindow::updateMeasurementTable()
{
    updateMeasurementTableColumn();
    int count = mTableWidgetMeasurement->rowCount();
    for(int i= 0;i<count;++i){
        updateMeasurement(i);
    }
}

void MainWindow::adjustPlotAxis()
{
    auto derta = (mYMaxData - mYMinData) / 20;
    ui->customPlot->yAxis->setRange(mYMinData - derta, mYMaxData + derta);
    derta = (mXMaxData - mXMinData) / 20;
    ui->customPlot->xAxis->setRange(mXMinData - derta, mXMaxData + derta);
}

void MainWindow::openFiles(const QStringList &fileNames)
{
    for (const QString &s : fileNames)
    {
        if (mOpenFiles.count(s))
        {
            mTextEditMessage->appendHtml("已打开:<b>" + s + "</b>");
            continue;
        }
        bool ret = mTreeModel->readElementsFile(mTreeModeReader, s);
        if (ret)
        {
            mOpenFiles.insert(s);
            mTextEditMessage->appendHtml("打开成功:<b>" + s + "</b>");
        }
        else
            mTextEditMessage->appendHtml("打开失败:<b>" + s + "</b>");
    }
    mpFilterProxyModel->setSourceModel(mTreeModel);
}

void MainWindow::openFile(const QString &fileName)
{
    if (mOpenFiles.count(fileName))
    {
        mTextEditMessage->appendHtml("已打开:<b>" + fileName + "</b>");
        return;
    }
    bool ret = mTreeModel->readElementsFile(mTreeModeReader, fileName);
    if (ret)
    {
        mOpenFiles.insert(fileName);
        mTextEditMessage->appendHtml("打开成功:<b>" + fileName + "</b>");
    }
    else
        mTextEditMessage->appendHtml("打开失败:<b>" + fileName + "</b>");
}
